import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyMessageQueue {

    Lock lock;

    Condition mEmptyQueue;
    Condition mFullQueue;

    MyMessage[] messages;

    int putIndex;
    int takeIndex;

    int count;

    public MyMessageQueue() {
        messages = new MyMessage[50];
        lock = new ReentrantLock();

        mEmptyQueue = lock.newCondition();
        mFullQueue = lock.newCondition();
    }


    final void enqueueMessage(MyMessage msg) {
        try {
            lock.lock();
            while (count == messages.length) {
                try {
                    mFullQueue.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            messages[putIndex] = msg;
            putIndex = (++putIndex == messages.length ? 0 : putIndex);
            count++;
            mEmptyQueue.signalAll();
        } finally {
            lock.unlock();
        }
    }

    final MyMessage next() {

        MyMessage msg = null;
        try {
            lock.lock();
            while (count == 0) {
                try {
                    mEmptyQueue.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

            msg = messages[takeIndex];
            messages[takeIndex] = null;
            takeIndex = (++takeIndex == messages.length ? 0 : takeIndex);
            count--;

        } finally {
            lock.unlock();
        }
        return msg;
    }


}
